package com.company.bookstore.controller.user_admin_module;


import com.company.bookstore.common.constant.RequestConstant;
import com.company.bookstore.common.result.MvcResult;
import com.company.bookstore.entities.user_admin_module.Admin;
import com.company.bookstore.entities.user_admin_module.Roles;
import com.company.bookstore.exception.user_admin_module.CustomException;
import com.company.bookstore.qo.user_admin_module.AdminQo;
import com.company.bookstore.qo.user_admin_module.UserQo;
import com.company.bookstore.service.user_admin_module.AdminService;
import com.company.bookstore.service.user_admin_module.RoleService;
import com.company.bookstore.service.user_admin_module.UserService;
import com.company.bookstore.validator.user_admin_module.AdminQoRegisterValidator;
import com.company.bookstore.validator.user_admin_module.AdminQoUpdateValidator;
import com.company.bookstore.validator.user_admin_module.ValidatorFactory;
import com.company.bookstore.vo.AdminVo;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.lang.Nullable;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.annotation.Resource;
import javax.management.relation.Role;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 管理员表 前端控制器
 * Security url 控制器 permissAll 的请求 不会被PreAuth
 *
 * </p>
 * https://blog.csdn.net/weixin_39220472/article/details/80873268
 *
 * @author 吴经纶
 * @blame Android Team
 * @since 2020-08-28
 */
@CrossOrigin(origins = "*",maxAge = 3600)
@Api(tags = "用户相关接口", description = "提供管理员相关的 Rest API")
@RestController
@Slf4j
@PreAuthorize(value = "hasRole('ROLE_ADMIN')")
@RequestMapping(path = "/admin")
public class AdminController {

    @Resource
    AdminService adminService;
    @Resource
    UserService userService;
    @Resource
    RoleService roleService;
    @Resource
    BCryptPasswordEncoder bCryptPasswordEncoder;






    @GetMapping("/list")
    public MvcResult<Object> getListOfAdmin(){
        try {
            List<Admin> adminList = adminService.list();
            List<Roles> roles = roleService.list();
            Map<Integer,Roles> map = new HashMap<>();
            roles.forEach(
               v->{
                   map.putIfAbsent(v.getId(),v);
               }
            );
            adminList.forEach(
                    v->{
                        v.setRoles(map.getOrDefault(v.getFkRoleId(),null));
                    }
            );
            return MvcResult.builder().code(200).message("获取管理员列表成功").object(adminList).build();
        }catch (Exception e){
            e.printStackTrace();
            return MvcResult.builder().code(500).message("获取管理员列表失败").build();
        }
    }






    @ApiIgnore
    @ApiOperation("测试管理员token")
    @GetMapping("/test")
    public MvcResult<Object> test(HttpServletRequest request){
        try {
            log.info(request.getHeader(RequestConstant.HTTP_LOGIN_JWT_HEADER));
            return MvcResult.LOGING_SUCCESS;
        }catch (Exception e){
            e.printStackTrace();
            return MvcResult.LOGING_ERROR;
        }
    }
    @PreAuthorize("hasAnyRole('ROLE_ADMIN','ROLE_BOOK','ROLE_ORDER','ROLE_DATA')")
    @ApiOperation("管理员信息接口")
    @GetMapping("/getInfo")
    public MvcResult<Object> getInfo()  {
//        HttpServletRequest request =((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
//        String token = request.getHeader(RequestConstant.HTTP_LOGIN_JWT_HEADER);
        try {
            String username =  SecurityContextHolder.getContext().getAuthentication().getName();
            Admin admin = (Admin) adminService.loadUserByUsername(username);
            System.out.println(admin.isEnabled());
            AdminVo adminVo = AdminVo.builder().build();
            BeanUtils.copyProperties(admin,adminVo);
            adminVo.setRole(roleService.getById(admin.getFkRoleId()));
            return MvcResult.builder().object(adminVo).code(200).message("获取信息成功").build();
        }catch (Exception e){
            return MvcResult.builder().message(e.getMessage()).code(500).build();
        }
    }

    @ApiOperation("注册管理员管理员接口")
    @PostMapping("/register")
    public MvcResult<Object> register(@RequestBody AdminQo adminQo) throws NoSuchMethodException, CustomException {

        ValidatorFactory.Invoke(AdminQoRegisterValidator.class.getName(),adminQo);

            if (!adminService.insertAdmin(adminQo.getAdminName(),bCryptPasswordEncoder.encode(adminQo.getPassword()),adminQo.getFkRoleId())){
                return MvcResult.REGISTER_FAIL;
            }
            return MvcResult.REGISTER_SUCCESS;

    }

    @ApiOperation("管理员资料修改接口")
    @PutMapping("")
    public MvcResult<Object> update(@RequestBody AdminQo adminQo) throws NoSuchMethodException, CustomException {

        if (adminService.updateAdminQo(adminQo)){
            return MvcResult.FIX_USER_SUCCESS;
        }else {
            return MvcResult.FIX_USER_FAIL;
        }
    }

    @ApiOperation("用户列表接口")
    @GetMapping("/all")
    public MvcResult<Object> getAll(@Nullable @RequestBody UserQo userQo){
        if (userQo == null){
            return MvcResult.builder().message("获取成功").code(200).object(userService.list()).build();
        }else {
            return MvcResult.builder().message("获取成功").code(200).object(userService.list()).build();
        }
    }


    @ApiOperation("用户删除接口")
    @DeleteMapping("/{id}")
    public MvcResult<Object> delete(@PathVariable Integer id){
        if (userService.removeById(id)){
            return MvcResult.DELETE_USER_SUCCESS;
        }else {
            return MvcResult.DELETE_USER_FAIL;
        }
    }
}

